<template>
  <div class="chart-container">
    <div class="mode-selector">
      <button
        v-for="mode in modes"
        :key="mode.value"
        @click="handleModeChange(mode.value)"
        :class="{ active: timeMode === mode.value }"
      >
        {{ mode.label }}
      </button>
    </div>

    <div ref="chart1" class="chart-item"></div>
    <div ref="chart2" class="chart-item"></div>
    <div ref="chart3" class="chart-item"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';
import axios from 'axios';
import { ref } from "vue";

export default {
  name: 'SharedAxisCharts',
  created() {
  let debounceTimer = null;
  this.fetchDataWithDebounce = (id) => {
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(() => {
      if (this.validatePatientId(id)) {
        this.fetchData(id);
      }
    }, 500);
  };
  },
  data() {
    return {
      modes: [
        { label: '一分钟', value: 'minute' },
        { label: '一小时', value: 'hour' },
        { label: '一天', value: 'day' },
      ],
      debounceTimer: null,
      currentRequest: null,
      currentUserId: '',
      timeMode: 'minute',
      chartData: {
        minute: [],
        hour: [],
        day: []
      },
      charts: [],
      source: null,
      dataCache: new Map(),
      baseOptions: {
        color: ['#00F2F7', '#F5804D', '#D5F51E'],
        grid: {
          top: 10,
          bottom: 10
        },
        tooltip: {
          trigger: 'axis',
          backgroundColor: 'rgba(0,36,80,0.9)',
          borderColor: '#00F2F7',
          textStyle: {
            color: '#fff'
          }
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          axisLabel: {
            show: false,
            color: '#fff'
          },
          axisLine: {
            show: false,
            lineStyle: {
              color: '#fff'
            }
          },
          axisTick: {
            show: false
          }
        },
        yAxis: {
          nameTextStyle: {
            color: '#fff'
          },
          axisLabel: {
            color: '#fff'
          },
          splitLine: {
            lineStyle: {
              color: 'rgba(255,255,255,0.1)'
            }
          }
        }
      }
    };
  },
  beforeDestroy() {
    // 清理防抖定时器
    if (this.debounceTimer) {
      clearTimeout(this.debounceTimer)
    }
  },
  props: {
    userId: {
      type: [String, Number],
      default: null,
      validator: value =>
        value === null || /^\d+$/.test(value.toString())
    }
  },
  mounted() {
    window.addEventListener('resize', this.handleResize);
  },
  watch: {
    userId: {
      immediate: true,
      handler(newVal) {
        if (this.validatePatientId(newVal)) {
          this.scheduleFetch()
        }
      }
    },
    timeMode() {
      this.scheduleFetch()
    }
  },
  methods: {
    scheduleFetch() {
    clearTimeout(this.debounceTimer)
    this.cancelCurrentRequest()

    this.debounceTimer = setTimeout(() => {
      this.executeFetch()
    }, 500)
  },

  // 执行数据获取
  async executeFetch() {
    try {
      if (!this.validatePatientId(this.userId)) return

      const cacheKey = `${this.userId}_${this.timeMode}`
      if (this.dataCache.has(cacheKey)) {
        this.applyCachedData(cacheKey)
        return
      }

      await this.fetchRemoteData()
    } catch (error) {
      this.handleFetchError(error)
    }
  },

  // 远程数据获取
async fetchRemoteData() {
  const source = axios.CancelToken.source()
  this.currentRequest = source

  // 记录当前请求的 ID 用于后续验证
  const requestId = this.userId
  const response = await axios.get('/liveData', {
    params: {
      id: requestId.toString(),
      mode: this.timeMode
    },
    cancelToken: source.token
  })

  // 验证数据结构并提取数据
  if (!this.validateResponse(response.data)) {
    throw new Error('Invalid response structure')
  }

  // 添加 ID 验证层（关键修改）
  const { id, data } = response.data
  if (id.toString() !== requestId.toString()) {
    throw new Error('Response ID mismatch')
  }

  // 存储带 ID 的数据结构
  this.updateDataCache({ id, data })
  this.updateCharts()
},

// 修改数据缓存方法
updateDataCache(payload) {
  const cacheKey = `${payload.id}_${this.timeMode}`
  this.chartData[this.timeMode] = payload.data
  this.dataCache.set(cacheKey, payload.data) // 存储原始数据
},

// 修改响应验证方法
validateResponse(data) {
  // 先验证基础结构
  if (!data || typeof data !== 'object' || !data.id || !data.data) {
    return false
  }

  // 继续原有数据格式验证
  const expectedLength = {
    minute: 6,
    hour: 6,
    day: 12
  }[this.timeMode]

  return (
    Array.isArray(data.data) &&
    data.data.length === 3 &&
    data.data.every(arr =>
      Array.isArray(arr) &&
      arr.length === expectedLength
    )
  )
},

  // 应用缓存数据
  applyCachedData(cacheKey) {
    this.chartData[this.timeMode] = this.dataCache.get(cacheKey)
    this.updateCharts()
  },

  // 请求取消处理
  cancelCurrentRequest() {
    if (this.currentRequest) {
      this.currentRequest.cancel('Request canceled')
      this.currentRequest = null
    }
  },

  // 统一错误处理
  handleFetchError(error) {
    if (axios.isCancel(error)) {
      console.log('Request canceled:', error.message)
      return
    }
    let message = '数据加载失败'
    if (!navigator.onLine) {
      message = '网络连接异常'
    } else if (error.response) {
      message = this.getServerErrorMessage(error.response.status)
    }
    this.$message.error(message)
    this.disposeCharts()
  },

  // 服务端错误消息映射
  getServerErrorMessage(status) {
    return {
      400: '请求参数错误',
      401: '认证失败',
      404: '患者不存在',
      500: '服务器内部错误'
    }[status] || `请求失败 (${status})`
  },

  // ID 验证
  validatePatientId(id) {
    const isValid = id && /^\d+$/.test(id.toString())
    !isValid && this.$message.error('无效的患者ID')
    return isValid
  },

  // 图表生命周期管理
  initCharts() {
    this.disposeCharts()

    this.charts = [0, 1, 2].map(index => {
      const domRef = this.$refs[`chart${index + 1}`]
      if (!domRef) return null

      const chart = echarts.init(domRef)
      this.configureChart(chart, index)
      return chart
    }).filter(Boolean)

    echarts.connect(this.charts)
  },

  // 图表配置
  configureChart(chart, index) {
    const config = {
      temperature: { unit: '℃', range: [35, 41] },
      heartRate: { unit: 'bpm', range: [30, 150] },
      bloodOxygen: { unit: '%', range: [40, 100] }
    }[index]

    chart.setOption({
      ...this.baseOptions,
      xAxis: { ...this.baseOptions.xAxis, data: this.generateXData() },
      yAxis: {
        ...this.baseOptions.yAxis,
        name: config.unit,
        min: config.range[0],
        max: config.range[1],
        interval: config.range[1] - config.range[0] > 50 ? 20 : 10
      },
      series: [{
        data: this.chartData[this.timeMode]?.[index] || [],
        type: 'line',
        smooth: true,
        lineStyle: {
          width: 2,
          color: this.baseOptions.color[index]
        },
        showSymbol: this.timeMode === 'day' // 按模式控制符号显示
      }]
    })
  },

  // 生成X轴标签
  generateXData() {
    const lengthMap = {
      minute: 6,
      hour: 6,
      day: 12
    }

    return Array.from({ length: lengthMap[this.timeMode] }, (_, i) => {
      const num = i + 1
      switch (this.timeMode) {
        case 'minute': return `${num * 10}秒`
        case 'hour': return `${num * 10}分钟`
        case 'day': return `${num * 2}小时`
        default: return ''
      }
    })
  },

  // 更新图表（带过渡动画）
  updateCharts() {
    this.isLoading = true
    this.$el.classList.add('chart-updating')

    this.$nextTick(() => {
      this.initCharts()
      this.isLoading = false
      this.$el.classList.remove('chart-updating')
    })
  },

  // 窗口resize处理
  handleResize() {
    this.charts.forEach(chart => {
      try {
        chart?.resize()
      } catch (error) {
        console.warn('图表resize失败:', error)
      }
    })
  },

  // 安全销毁图表实例
  disposeCharts() {
    this.charts.forEach(chart => {
      try {
        chart?.dispose()
      } catch (error) {
        console.warn('图表销毁失败:', error)
      }
    })
    this.charts = []
  }
}
};
</script>

<style scoped>
.chart-container {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  padding: 0;
  margin: 0 auto;
  overflow: hidden;
  background-color: #b9c8da23;
}

.mode-selector {
  padding: 15px 0;
  text-align: center;
}

button {
  margin: 0 10px;
  padding: 8px 20px;
  background: transparent;
  border: 1px solid #00F2F7;
  color: #00F2F7;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s;
}

button.active {
  background: #00F2F7;
  color: #002450;
  font-weight: bold;
}

.chart-item {
  flex: 1;
  min-height: 200px;
  overflow: hidden;
}
</style>